package com.example.common.mvi

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch

/**
 * MVI架构的基础Fragment
 * @param VDB ViewDataBinding类型
 * @param VM ViewModel类型
 * @param I Intent类型
 * @param S ViewState类型
 */
abstract class BaseFragment<VDB : ViewDataBinding, VM : BaseViewModel<I, S, *>, I : MviIntent, S : MviViewState> : Fragment() {

    protected lateinit var binding: VDB
    protected abstract val viewModel: VM

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false)
        binding.lifecycleOwner = viewLifecycleOwner
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setupViews()
        observeViewModel()
    }

    /**
     * 观察ViewModel
     */
    private fun observeViewModel() {
        // 观察ViewState
        lifecycleScope.launch {
            viewModel.viewState.collect { state ->
                renderViewState(state)
            }
        }

        // 观察单次事件
        lifecycleScope.launch {
            viewModel.singleEvent.collect { event ->
                handleSingleEvent(event)
            }
        }
    }

    /**
     * 处理单次事件
     */
    protected open fun handleSingleEvent(event: SingleEvent) {
        when (event) {
            is SingleEvent.ShowToast -> {
                Toast.makeText(requireContext(), event.message, Toast.LENGTH_SHORT).show()
            }
            is SingleEvent.ShowError -> {
                Toast.makeText(requireContext(), event.error, Toast.LENGTH_LONG).show()
            }
            is SingleEvent.Navigate -> {
                // 处理导航逻辑
                handleNavigation(event.route)
            }
            is SingleEvent.ShowLoading -> {
                showLoading()
            }
            is SingleEvent.HideLoading -> {
                hideLoading()
            }
        }
    }

    /**
     * 发送Intent到ViewModel
     */
    protected fun sendIntent(intent: I) {
        viewModel.sendIntent(intent)
    }

    /**
     * 获取布局ID的抽象方法
     */
    protected abstract fun getLayoutId(): Int

    /**
     * 设置视图的抽象方法
     */
    protected abstract fun setupViews()

    /**
     * 渲染ViewState的抽象方法
     */
    protected abstract fun renderViewState(state: S)

    /**
     * 处理导航的方法，子类可重写
     */
    protected open fun handleNavigation(route: String) {
        // 默认实现为空，子类可重写
    }

    /**
     * 显示加载状态，子类可重写
     */
    protected open fun showLoading() {
        // 默认实现为空，子类可重写
    }

    /**
     * 隐藏加载状态，子类可重写
     */
    protected open fun hideLoading() {
        // 默认实现为空，子类可重写
    }
}